/*
 * =====================================================================================
 *
 *       Filename:  Deck.cpp
 *
 *    Description:  The implementation of Deck.h for decking the cards from Card.h and Card.cpp
 *
 *        Version:  1.0
 *        Created:  10/24/11 15:33:37
 *       Revision:  none
 *       Compiler:  g++ on Darwin x86_64
 *
 *         Author:  LittleQ Su (98703060@nccu.edu.tw), 
 *        Company:  National Chengchi University, The Department of Computer Science
 *
 * =====================================================================================
 */

#include "headers.h"

// Public
Deck::Deck() {
    Card::Suit suit;
    this -> dealIndex = 0;

    for (int s = 1 ; s <= SUIT_MAX ; s++) {
        suit = this -> _getSuit(s);
        for (int r = 1; r <= RANK_MAX ; r++) {
            this -> cards[this->dealIndex] = *(new Card(r, suit));
            this -> dealIndex ++ ;
        }
    }
    this -> dealIndex = 0;

}

void Deck::shuffle() {
    int draw_pos;
    this -> dealIndex = 0;
    
    for (int rt = 0; rt < RAND_TIME ; ++rt) {
        draw_pos = (rand() % (this->cardsRemaining() - 1)) + 1;
        this -> cardSwap(0, draw_pos);
    }
}

void Deck::shuffle(bool randomize) {
    if ( randomize == true ) {
        srand((unsigned) time(0));
    }
    this -> shuffle();
}

Card Deck::dealCard() {
    int index = this -> dealIndex;
    this -> dealIndex ++;
    return this -> cards[index];

}

int Deck::cardsRemaining() const{
    return DECK_MAX - this->dealIndex;
}

// Private :

void Deck::cardSwap( int idx1, int idx2 ) {
    Card temp_card;

    temp_card = this -> cards[idx2];
    this -> cards[idx2] = this -> cards[idx1];
    this -> cards[idx1] = temp_card;

}

Card::Suit Deck::_getSuit(int suitNumber) {
    
    switch ( suitNumber ) {
        case 1:
            return Card::CLUBS;
        case 2:	
            return Card::DIAMONDS;
        case 3:	
            return Card::HEARTS;
        case 4:
            return Card::SPADES;
        default:	
            return Card::CLUBS;
    }
}
